const db = uniCloud.database();
const dbCmd = db.command;
const attendanceCollection = db.collection('attendance');

module.exports = {
  _before: function() {
    // 通用前置处理
  },
  
  /**
   * 获取课程某日期的考勤记录
   * @param {String} course_id - 课程ID
   * @param {String} date - 日期，格式为YYYY-MM-DD
   * @returns {Array} 考勤记录列表
   */
  async getCourseAttendanceByDate(course_id, date) {
    if (!course_id) throw new Error('课程ID不能为空');
    if (!date) throw new Error('日期不能为空');
    
    // 将日期转换为时间范围
    const startDate = new Date(date);
    startDate.setHours(0, 0, 0, 0);
    
    const endDate = new Date(date);
    endDate.setHours(23, 59, 59, 999);
    
    // 获取该课程的所有报名学生
    const enrollments = await db.collection('enrollment')
      .aggregate()
      .match({
        course_id,
        status: 1
      })
      .lookup({
        from: 'student',
        localField: 'student_id',
        foreignField: '_id',
        as: 'student'
      })
      .project({
        _id: 1,
        student_id: 1,
        student: { $arrayElemAt: ['$student', 0] }
      })
      .end()
      .then(res => res.data);
    
    // 获取指定日期的考勤记录
    const attendances = await attendanceCollection
      .where({
        course_id,
        date: dbCmd.gte(startDate).and(dbCmd.lte(endDate))
      })
      .get()
      .then(res => res.data);
    
    // 将考勤记录转换为以学生ID为键的对象
    const attendanceMap = attendances.reduce((map, attendance) => {
      map[attendance.student_id] = attendance;
      return map;
    }, {});
    
    // 构建每个学生的考勤记录
    return enrollments.map(enrollment => {
      const attendance = attendanceMap[enrollment.student_id] || {
        student_id: enrollment.student_id,
        course_id,
        date: startDate,
        status: null,
        remarks: ''
      };
      
      return {
        ...attendance,
        student: enrollment.student
      };
    });
  },
  
  /**
   * 获取学生在课程中的考勤记录
   * @param {String} student_id - 学生ID
   * @param {String} course_id - 课程ID
   * @param {Object} params - 查询参数
   * @param {String} params.start_date - 开始日期（可选）
   * @param {String} params.end_date - 结束日期（可选）
   * @param {Number} params.page - 页码
   * @param {Number} params.pageSize - 每页数量
   * @returns {Object} 考勤记录列表和总数
   */
  async getStudentAttendance(student_id, course_id, params = {}) {
    if (!student_id) throw new Error('学生ID不能为空');
    if (!course_id) throw new Error('课程ID不能为空');
    
    const { start_date, end_date, page = 1, pageSize = 10 } = params;
    
    // 构建查询条件
    const query = {
      student_id,
      course_id
    };
    
    if (start_date && end_date) {
      const startDate = new Date(start_date);
      startDate.setHours(0, 0, 0, 0);
      
      const endDate = new Date(end_date);
      endDate.setHours(23, 59, 59, 999);
      
      query.date = dbCmd.gte(startDate).and(dbCmd.lte(endDate));
    }
    
    // 查询总数
    const countResult = await attendanceCollection.where(query).count();
    const total = countResult.total;
    
    // 查询分页数据
    const list = await attendanceCollection
      .where(query)
      .skip((page - 1) * pageSize)
      .limit(pageSize)
      .orderBy('date', 'desc')
      .get()
      .then(res => res.data);
    
    return {
      list,
      total,
      page,
      pageSize
    };
  },
  
  /**
   * 保存学生考勤记录
   * @param {String} student_id - 学生ID
   * @param {String} course_id - 课程ID
   * @param {String} date - 日期
   * @param {Number} status - 考勤状态：1 出勤，0 缺勤，2 请假
   * @param {String} remarks - 备注
   * @returns {Object} 保存结果
   */
  async saveAttendance(student_id, course_id, date, status, remarks = '') {
    if (!student_id) throw new Error('学生ID不能为空');
    if (!course_id) throw new Error('课程ID不能为空');
    if (!date) throw new Error('日期不能为空');
    if (![0, 1, 2].includes(status)) throw new Error('考勤状态不正确');
    
    // 将日期转换为时间对象
    const attendanceDate = new Date(date);
    
    // 查询是否已存在考勤记录
    const existingAttendance = await attendanceCollection
      .where({
        student_id,
        course_id,
        date: dbCmd.gte(new Date(attendanceDate.setHours(0, 0, 0, 0))).and(
          dbCmd.lte(new Date(attendanceDate.setHours(23, 59, 59, 999)))
        )
      })
      .get()
      .then(res => res.data[0]);
    
    if (existingAttendance) {
      // 更新现有记录
      await attendanceCollection.doc(existingAttendance._id).update({
        status,
        remarks,
        update_date: new Date()
      });
      
      return {
        id: existingAttendance._id,
        success: true
      };
    } else {
      // 创建新记录
      const result = await attendanceCollection.add({
        student_id,
        course_id,
        date: attendanceDate,
        status,
        remarks,
        create_date: new Date(),
        update_date: new Date()
      });
      
      return {
        id: result.id,
        success: true
      };
    }
  },
  
  /**
   * 批量保存考勤记录
   * @param {Array} records - 考勤记录数组
   * @returns {Object} 保存结果
   */
  async batchSaveAttendance(records) {
    if (!records || !Array.isArray(records) || records.length === 0) {
      throw new Error('考勤记录数组不能为空');
    }
    
    const results = [];
    
    for (const record of records) {
      const { student_id, course_id, date, status, remarks } = record;
      
      // 验证必要字段
      if (!student_id || !course_id || !date || status === undefined) {
        continue;
      }
      
      // 保存单个考勤记录
      const result = await this.saveAttendance(student_id, course_id, date, status, remarks);
      results.push(result);
    }
    
    return {
      results,
      success: true
    };
  },
  
  /**
   * 获取课程考勤统计
   * @param {String} course_id - 课程ID
   * @param {String} start_date - 开始日期
   * @param {String} end_date - 结束日期
   * @returns {Object} 考勤统计结果
   */
  async getCourseAttendanceStats(course_id, start_date, end_date) {
    if (!course_id) throw new Error('课程ID不能为空');
    if (!start_date) throw new Error('开始日期不能为空');
    if (!end_date) throw new Error('结束日期不能为空');
    
    // 转换日期为 Date 对象
    const startDate = new Date(start_date);
    startDate.setHours(0, 0, 0, 0);
    
    const endDate = new Date(end_date);
    endDate.setHours(23, 59, 59, 999);
    
    // 获取课程的所有报名学生
    const enrollments = await db.collection('enrollment')
      .aggregate()
      .match({
        course_id,
        status: 1
      })
      .lookup({
        from: 'student',
        localField: 'student_id',
        foreignField: '_id',
        as: 'student'
      })
      .project({
        _id: 1,
        student_id: 1,
        student: { $arrayElemAt: ['$student', 0] }
      })
      .end()
      .then(res => res.data);
    
    // 获取学生ID列表
    const studentIds = enrollments.map(e => e.student_id);
    
    // 获取时间范围内所有考勤记录
    const attendances = await attendanceCollection
      .where({
        course_id,
        student_id: dbCmd.in(studentIds),
        date: dbCmd.gte(startDate).and(dbCmd.lte(endDate))
      })
      .get()
      .then(res => res.data);
    
    // 按学生统计考勤情况
    const studentStats = studentIds.map(studentId => {
      const studentAttendances = attendances.filter(a => a.student_id === studentId);
      const student = enrollments.find(e => e.student_id === studentId).student;
      
      // 统计各种状态的数量
      const stats = {
        present: studentAttendances.filter(a => a.status === 1).length,
        absent: studentAttendances.filter(a => a.status === 0).length,
        leave: studentAttendances.filter(a => a.status === 2).length,
        total: studentAttendances.length
      };
      
      return {
        student_id: studentId,
        student_name: student.name,
        stats
      };
    });
    
    // 统计整体出勤情况
    const totalStats = {
      present: attendances.filter(a => a.status === 1).length,
      absent: attendances.filter(a => a.status === 0).length,
      leave: attendances.filter(a => a.status === 2).length,
      total: attendances.length
    };
    
    return {
      studentStats,
      totalStats,
      period: {
        start_date: startDate,
        end_date: endDate
      }
    };
  },
  
  /**
   * 获取学生考勤统计
   * @param {String} student_id - 学生ID
   * @param {String} start_date - 开始日期
   * @param {String} end_date - 结束日期
   * @returns {Object} 考勤统计结果
   */
  async getStudentAttendanceStats(student_id, start_date, end_date) {
    if (!student_id) throw new Error('学生ID不能为空');
    if (!start_date) throw new Error('开始日期不能为空');
    if (!end_date) throw new Error('结束日期不能为空');
    
    // 转换日期为 Date 对象
    const startDate = new Date(start_date);
    startDate.setHours(0, 0, 0, 0);
    
    const endDate = new Date(end_date);
    endDate.setHours(23, 59, 59, 999);
    
    // 获取学生的报名课程
    const enrollments = await db.collection('enrollment')
      .aggregate()
      .match({
        student_id,
        status: 1
      })
      .lookup({
        from: 'course',
        localField: 'course_id',
        foreignField: '_id',
        as: 'course'
      })
      .project({
        _id: 1,
        course_id: 1,
        course: { $arrayElemAt: ['$course', 0] }
      })
      .end()
      .then(res => res.data);
    
    // 获取课程ID列表
    const courseIds = enrollments.map(e => e.course_id);
    
    // 获取时间范围内所有考勤记录
    const attendances = await attendanceCollection
      .where({
        student_id,
        course_id: dbCmd.in(courseIds),
        date: dbCmd.gte(startDate).and(dbCmd.lte(endDate))
      })
      .get()
      .then(res => res.data);
    
    // 按课程统计考勤情况
    const courseStats = courseIds.map(courseId => {
      const courseAttendances = attendances.filter(a => a.course_id === courseId);
      const course = enrollments.find(e => e.course_id === courseId).course;
      
      // 统计各种状态的数量
      const stats = {
        present: courseAttendances.filter(a => a.status === 1).length,
        absent: courseAttendances.filter(a => a.status === 0).length,
        leave: courseAttendances.filter(a => a.status === 2).length,
        total: courseAttendances.length
      };
      
      return {
        course_id: courseId,
        course_name: course.name,
        stats
      };
    });
    
    // 统计整体出勤情况
    const totalStats = {
      present: attendances.filter(a => a.status === 1).length,
      absent: attendances.filter(a => a.status === 0).length,
      leave: attendances.filter(a => a.status === 2).length,
      total: attendances.length
    };
    
    return {
      courseStats,
      totalStats,
      period: {
        start_date: startDate,
        end_date: endDate
      }
    };
  }
}; 